home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-01
/
smailsrc.zip
/
UUPC.ZIP
/
DCPXFER.C
< prev
next >
Wrap
Text File
|
1990-04-21
|
8KB
|
425 lines
/*
For best results in visual layout while viewing this file, set
tab stops to every 8 columns.
*/
/*
dcpxfer.c
Revised edition of dcp
Stuart Lynne May/87
Copyright (c) Richard H. Lamb 1985, 1986, 1987
Changes Copyright (c) Stuart Lynne 1987
Maintenance Notes:
01Nov87 - that strncpy should be a memcpy! - Jal
*/
/* "DCP" a uucp clone. Copyright Richard H. Lamb 1985,1986,1987 */
/* file send routines */
#include "dcp.h"
#include <ctype.h>
static unsigned char rpacket[MAXPACK], spacket[MAXPACK];
static int S_size; /* number of bytes in the spacket buffer */
static char fromfile[132], tofile[132];
static int bufill(), bufwrite(), getfile();
/*************** SEND PROTOCOL ***************************/
/*
s d a t a
Send File Data
*/
char sdata()
{
for ( ; ; ) {
if ((*sendpkt)(spacket, S_size, 0)) /* send data */
return 0; /* trouble! */
if ((S_size = bufill(spacket)) == 0) /* get data from file */
return 'Z'; /* if EOF set state to that */
}
} /*sdata*/
/*
b u f i l l
Get a bufferful of data from the file that's being sent.
(Should perform input buffering here, perhaps 4K at a time.)
*/
static int bufill(buffer)
char *buffer;
{
return read(fp, buffer, pktsize); /* Handle partial buffer */
} /*bufill*/
/*
b u f w r i t e
Write a bufferful of data to the file that's being received.
(Should perform output buffering here, perhaps 4K at a time.)
*/
static int bufwrite(buffer, len)
char *buffer;
int len;
{
return write(fp, buffer, len); /* Write incoming data to file */
} /*bufwrite*/
/*
s b r e a k
Send Break (EOT)
*/
char sbreak()
{
int len;
strcpy(spacket, "H");
if ((*sendpkt)(spacket, 0, 1))
return 0;
if ((*getpkt)(spacket, &len))
return 0;
printmsg(2, "Switching modes.");
return (spacket[1] == 'N') ? 'G' : 'Y';
} /*sbreak*/
/*
s e o f
Send End-Of-File
*/
char seof()
{
char hostfile[132];
int len;
if ((*sendpkt)(spacket, 0, 0))
return 0;
if ((*getpkt)(spacket, &len))
return 0; /* receive CY or CN */
if (!equaln(spacket, "CY", 2))
return 0; /* can't send file */
close(fp);
fp = -1;
importpath(hostfile, fromfile);
unlink(hostfile);
printmsg(0, "Transfer of %s (%s) completed.", fromfile, hostfile);
/* Have to write the SYSLOG file someday!
fprintf(syslog, "%s!%s (%d/%d-%d:%d:%d) -> %ld / %ld secs",
host, id, month, day, hour, minute, seconds, size, secs);
*/
return 'F'; /* go get the next file to send */
} /*seof*/
/*
s f i l e
Send File Header
*/
char sfile()
{
char hostfile[132];
int len;
if (fp == -1) { /* if not already open */
printmsg(3, "looking in work file...");
if (getfile()) { /* get next request from current work file */
fclose(fwork);
fwork = nil(FILE);
unlink(workfile); /* delete completed call file */
return 'B'; /* end sending session */
}
importpath(hostfile, fromfile);
printmsg(3, "Opening %s (%s) for sending.", fromfile, hostfile);
if ((fp = open(hostfile, 0)) == -1) { /* open file to sent */
printmsg(0, "Cannot open file %s (%s).", fromfile, hostfile);
return 'A';
}
} else
return 'A'; /* Something's already open. We're in trouble! */
printmsg(0, "Sending %s (%s) as %s.", fromfile, hostfile, tofile);
strcpy(spacket, tofile);
if ((*sendpkt)(spacket, 0, 1))
return 0; /* send 'S fromfile tofile user - tofile 0666' */
if ((*getpkt)(spacket, &len))
return 0;
if (spacket[1] != 'Y')
return 'A'; /* If other side says no, then quit */
S_size = bufill(spacket);
return 'D';
} /*sfile*/
/*
s i n i t
Send Initiate: send this host's parameters and get other side's back.
*/
char sinit()
{
return (*openpk)() ? 'A' : 'B';
} /*sinit*/
/*
g e t f i l e
Reads the next line from the presently open call file
(*workfile) and determines from this the next file to be sent
(*fromfile). If there are no more, TRUE is returned.
** A fix for "R from to 0666" should be done here to recieve files
in addition to sending them. The appropriate "state letter"
i.e. "R" should be returned to the send "master" or "slave"
state switching table in "dcp.c".
I did not implement this since the majority of uucp transactions
appear to be "S from to 0666" type. R.H.Lamb 1/87
*/
static int getfile()
{
int i;
char line[132];
register char *cp;
if (fgets(line, BUFSIZ, fwork) == nil(char))
return TRUE;
sscanf(line + 2, "%s ", fromfile);
for (i = 0, cp = line; *cp!='\0'; i++, cp++) {
if (equaln(cp, "0666", 4))
break;
}
cp += 4;
*cp = '\0';
strcpy(tofile, line);
printmsg(3, "getfile: fromfile=%s, tofile=%s.", fromfile, tofile);
return FALSE;
} /*getfile*/
/*********************** MISC SUB SUB PROTOCOL *************************/
/*
s c h k d i r
scan spooling directory for C.* files for the other system
*/
char schkdir()
{
char c;
if ((c = scandir(rmtname)) == 'Q')
return 'Y';
if (c == 'S') {
strcpy(rpacket, "HN");
if ((*sendpkt)(rpacket, 0, 1))
return 0;
}
return 'B';
} /*schkdir*/
/*
e n d p
end the protocol
*/
char endp()
{
strcpy(rpacket, "HY");
(*sendpkt)(rpacket, 0, 2); /* don't wait for ACK */
(*closepk)();
return 'P';
} /*endp*/
/*********************** RECIEVE PROTOCOL **********************/
/*
r d a t a
Receive Data
*/
char rdata()
{
int len;
if ((*getpkt)(rpacket, &len))
return 0;
if (len == 0) {
close(fp);
strcpy(rpacket, "CY");
if ((*sendpkt)(rpacket, 0, 1))
return 0;
printmsg(0, "Transfer completed.");
return 'F';
}
/* write incoming data to the file */
if (bufwrite(rpacket, len) == -1) {
printmsg(0, "Error writing data to file.");
return 'A';
}
return 'D'; /* Remain in data state */
} /*rdata*/
/*
r f i l e
Receive File Header
*/
char rfile()
{
char buf[256], tmpfilename[256];
char *flds[10], *cp;
printmsg(3, "rfile: entered");
for (cp = buf; ; ) {
int len;
if ((*getpkt)(rpacket, &len))
return 0;
memcpy(cp, rpacket, len);
cp += len;
if (cp[-1] == '\0')
break;
}
if ((buf[0] & 0x7f) == 'H')
return 'C'; /* the other side (master) is done */
printmsg(3, "rfile: command \"%s\"", buf);
getargs(buf, flds);
cp = flds[2];
printmsg(3, "rfile: destination \"%s\"", cp);
/* trim leading ~/ off if it's there */
if (equaln(cp, "~/", 2))
strcpy(tmpfilename, cp + 1);
else
strcpy(tmpfilename, cp);
/* check if the name is a directory name (end with a '/') */
if (cp[strlen(cp) - 1] == '/') {
printmsg(3, "rfile: destination is directory \"%s\"", flds[1]);
if ((cp = strrchr(flds[1], '/')) == nil(char))
cp = flds[1];
else
cp++;
printmsg(3, "rfile: dironly add \"%s\"", cp);
strcat(tmpfilename, cp);
}
printmsg(3, "rfile: receive file \"%s\"", tmpfilename);
/* let host munge filename as appropriate */
importpath(tofile, tmpfilename);
printmsg(3, "rfile: host file \"%s\"", tofile);
if (equaln(flds[2], "~/", 2)) {
mkfilename(tmpfilename, pubdir, tofile);
strcpy(tofile, tmpfilename);
printmsg(3, "rfile: ~/ expansion \"%s\"", tofile);
}
if ((fp = CREAT(tofile, 0775, BINARY)) == -1) { /* open a new file */
printmsg(0, "cannot create %s", tofile);
return 'A'; /* Give up if we can't */
}
printmsg(1, "Receiving \"%s\" as \"%s\"", flds[1], tofile);
strcpy(rpacket, "SY");
if ((*sendpkt)(rpacket, 0, 1))
return 0;
return 'D'; /* Switch to data state */
} /*rfile*/
/*
r i n i t
Receive Initialization
*/
char rinit()
{
return ((*openpk)()) ? 0 : 'F';
} /*rinit*/